/*
 * 文件名： MicroPayPabSericeImpl.java
 * 
 * 工程名称: bis-service
 *
 * Gopay
 *
 * 创建日期： 2018年1月13日
 *
 * Copyright(C) 2018, by www.gopay.com.cn Inc.All rights reserved.
 *
 * 原始作者: 宣广海
 *
 */
package com.gopay.bis.service.bank.impl.micro;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.manager.bank.micro.MicroPayPabManager;
import com.gopay.bis.manager.bank.scan.ScanPayPabManager;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.PabConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.ScanPayBaseMessage;
import com.gopay.common.domain.bank.pab.agpay.PabTransResMsg;
import com.gopay.common.domain.bank.pab.agpay.res.PayCancelResMsg;
import com.gopay.common.domain.bank.pab.agpay.res.PayOrderResMsg;
import com.gopay.common.domain.bank.pab.agpay.res.PayRefundQueryResMsg;
import com.gopay.common.domain.bank.pab.agpay.res.PayRefundResMsg;
import com.gopay.common.domain.bank.pab.agpay.res.PayStatusResMsg;
import com.gopay.common.domain.bank.wechat.micro.req.MicroPayReqMsg;
import com.gopay.common.domain.bank.wechat.micro.req.MicroReverseReqMsg;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.TransUtil;
import com.gopay.remote.bank.MicroPayInteractRemoteService;

/**
 * 
 *
 * @author 宣广海
 *
 * @version
 *
 * @since 2018年1月13日
 */
public class MicroPayPabSericeImpl implements MicroPayInteractRemoteService {
	/**
	 * 日志对象
	 */
	private static Logger logger = LoggerFactory.getLogger(MicroPayPabSericeImpl.class);
	@Resource(name = "microPayPabManager")
	private MicroPayPabManager microPayPabManager;
	@Resource(name = "scanPayPabManager")
	private ScanPayPabManager scanPayPabManager;

	@Override
	public Result pay(BaseMessage base) throws GopayException {
		logger.info("------------MicroPayPabSericeImpl pay start-------------");
		long beginTime = System.currentTimeMillis();
		Result result = new Result(false);
		try {
			MicroPayReqMsg message = new MicroPayReqMsg();
			BeanUtils.copyProperties(base, message);
			PabTransResMsg<PayOrderResMsg> resMessage = (PabTransResMsg<PayOrderResMsg>) microPayPabManager
					.payment(message);
			Map<String, String> param = new HashMap<String, String>();
			PayOrderResMsg orderRes = resMessage.getBody();
			result.setDefaultModel(true);
			result.setModel("res", resMessage);
			if (PabConstants.SUCCESS.equals(resMessage.getErrcode())
					&& PabConstants.ORDER_SUCCESS.equals(orderRes.getStatus())) {
				// 支付成功
				param.put("orderId", base.getOrderId());
				param.put("amt",
						new BigDecimal(TransUtil.amountConvert2Yuan(String.valueOf(orderRes.getTrade_amount())))
								.toString());
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "00");
				param.put("retCode", "00");
				param.put("retMsg", "验签成功");
				param.put("isFront", String.valueOf(false));
				result.setModel("isNotifyCashier", param);
				result.setSuccess(true);
				result.setOrderStatus(true);
			} else if (PabConstants.SUCCESS.equals(resMessage.getErrcode())
					&& PabConstants.ORDER_WAIT_PWD.equals(orderRes.getStatus())) {
				// 需要用户输入支付密码
				param.put("orderId", base.getOrderId());
				param.put("amt",
						new BigDecimal(TransUtil.amountConvert2Yuan(String.valueOf(orderRes.getTrade_amount())))
								.toString());
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "02");
				param.put("retCode", "01");
				param.put("retMsg", resMessage.getMsg());
				param.put("isFront", String.valueOf(false));
				result.setModel("isNotifyCashier", param);
				result.setSuccess(true);
				result.setErrorMsg(resMessage.getMsg());
				result.setOrderStatus(false);
			} else {
				param.put("orderId", base.getOrderId());
				param.put("amt", base.getAmount().toString());
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "01");
				param.put("retCode", "01");
				String errorMessage = resMessage.getMsg();
				param.put("retMsg", errorMessage);
				param.put("isFront", String.valueOf(false));
				result.setModel("isNotifyCashier", param);
				result.setSuccess(true);
				result.setErrorMsg(errorMessage);
				result.setOrderStatus(false);
			}
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7025);
		}
		long endTime = System.currentTimeMillis();
		logger.info("------ MicroPayPabSericeImpl pay end，耗时(ms):" + (endTime - beginTime));
		return result;
	}

	@Override
	public Result orderQuery(BaseMessage base) throws GopayException {

		logger.info("------------MicroPayPabSericeImpl orderQuery start-------------");
		long beginTime = System.currentTimeMillis();
		/**
		 * 定义返回对象
		 */
		Result result = new Result();
		ScanPayBaseMessage scanPayBase = new ScanPayBaseMessage();
		BeanUtils.copyProperties(base, scanPayBase);
		try {
			@SuppressWarnings({ "unchecked" })
			PabTransResMsg<PayStatusResMsg> resMessage = (PabTransResMsg<PayStatusResMsg>) scanPayPabManager
					.orderQuery(scanPayBase);
			if (("".equals(resMessage.getBody().getTrade_amount()))
					|| (null == resMessage.getBody().getTrade_amount())) {
				resMessage.setAmount(base.getAmount());
			} else {
				resMessage.setAmount(new BigDecimal(
						TransUtil.amountConvert2Yuan(String.valueOf(resMessage.getBody().getTrade_amount()))));
			}
			result.setDefaultModel(resMessage);
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		}
		long endTime = System.currentTimeMillis();
		logger.info("------ MicroPayPabSericeImpl orderQuery end，耗时(ms):" + (endTime - beginTime));
		return result;

	}

	@Override
	public Result refund(BaseMessage base) throws GopayException {
		logger.info("------------MicroPayPabSericeImpl refund start-------------");
		long beginTime = System.currentTimeMillis();
		/**
		 * 定义返回对象
		 */
		Result result = new Result(false);
		ScanPayBaseMessage scanPayBase = new ScanPayBaseMessage();
		BeanUtils.copyProperties(base, scanPayBase);
		try {
			@SuppressWarnings("unchecked")
			PabTransResMsg<PayRefundResMsg> resMsg = (PabTransResMsg<PayRefundResMsg>) scanPayPabManager.refund(scanPayBase);
			if (resMsg != null) {
				if ("0".equals(resMsg.getErrcode()) && "0".equals(resMsg.getBody().getStatus())) {
					result.setDefaultModel(resMsg);
					result.setSuccess(true);
					// 接收成功
					result.setModel("falg", true);
				} else {
					result.setSuccess(false);
					result.setModel("falg", false);
					result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
					result.setErrorMsg(resMsg.getMsg());
				}
			} else {
				result.setSuccess(false);
				result.setModel("falg", false);
				result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
			}
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
		}
		long endTime = System.currentTimeMillis();
		logger.info("------ MicroPayPabSericeImpl refund end，耗时(ms):" + (endTime - beginTime));
		return result;
	}

	@Override
	public Result refundQuery(BaseMessage base) throws GopayException {
		logger.info("------------MicroPayPabSericeImpl refundQuery start-------------");
		long beginTime = System.currentTimeMillis();
		/**
		 * 定义返回对象
		 */
		Result result = new Result();
		ScanPayBaseMessage scanPayBase = new ScanPayBaseMessage();
		BeanUtils.copyProperties(base, scanPayBase);
		try {
			@SuppressWarnings({ "unchecked" })
			PabTransResMsg<PayRefundQueryResMsg> resMessage = (PabTransResMsg<PayRefundQueryResMsg>) scanPayPabManager
					.refundOrderQuery(scanPayBase);
			result.setDefaultModel(resMessage);
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		}
		long endTime = System.currentTimeMillis();
		logger.info("------ MicroPayPabSericeImpl refundQuery end，耗时(ms):" + (endTime - beginTime));
		return result;
	}

	@Override
	public Result reverse(BaseMessage base) throws GopayException {
		Result result = new Result(false);
		try {
			MicroReverseReqMsg message = new MicroReverseReqMsg();
			BeanUtils.copyProperties(base, message);
			PabTransResMsg<PayCancelResMsg> resMessage = (PabTransResMsg<PayCancelResMsg>) microPayPabManager
					.reverse(message);
			logger.info("------ resMessage" + resMessage.getBody().getStatus());
			Map<String, String> param = new HashMap<String, String>();
			result.setDefaultModel(true);
			if (PabConstants.SUCCESS.equals(resMessage.getErrcode())) {
				param.put("orderId", base.getOrderId());
				param.put("amt", base.getAmount().toString());
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "00");
				param.put("retCode", "00");
				param.put("retMsg", "验签成功");
				param.put("isFront", String.valueOf(false));
				result.setModel("isNotifyCashier", param);
				result.setSuccess(true);
				result.setOrderStatus(true);
			} else {
				param.put("orderId", base.getOrderId());
				param.put("amt", base.getAmount().toString());
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "01");
				param.put("retCode", "01");
				// 记录数据库失败信息 add by zhengxue 20170313
				String errorMessage = resMessage.getMsg();
				param.put("retMsg", errorMessage);
				param.put("isFront", String.valueOf(false));
				result.setModel("isNotifyCashier", param);
				result.setSuccess(true);
				result.setOrderStatus(false);
			}
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			// 需新增错误码
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E1181);
		}
		return result;
	}

	@Override
	public Result reverseQuery(BaseMessage base) throws GopayException {
		logger.info("------------MicroPayPabSericeImpl orderQuery start-------------");
		long beginTime = System.currentTimeMillis();
		/**
		 * 定义返回对象
		 */
		Result result = new Result();
		ScanPayBaseMessage scanPayBase = new ScanPayBaseMessage();
		BeanUtils.copyProperties(base, scanPayBase);
		try {
			@SuppressWarnings({ "unchecked" })
			PabTransResMsg<PayStatusResMsg> resMessage = (PabTransResMsg<PayStatusResMsg>) scanPayPabManager
					.orderQuery(scanPayBase);
			if (("".equals(resMessage.getBody().getTrade_amount()))
					|| (null == resMessage.getBody().getTrade_amount())) {
				resMessage.setAmount(base.getAmount());
			} else {
				resMessage.setAmount(new BigDecimal(
						TransUtil.amountConvert2Yuan(String.valueOf(resMessage.getBody().getTrade_amount()))));
			}
			result.setDefaultModel(resMessage);
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		}
		long endTime = System.currentTimeMillis();
		logger.info("------ MicroPayPabSericeImpl orderQuery end，耗时(ms):" + (endTime - beginTime));
		return result;
	}
}
